#coding: utf-8

version = '0.1'

from parsers import DelphiParser

class Reference(object):
    def __init__(self, name, targets):
        self.name = name
        self.targets = targets
        
    def __str__(self):
        return '%s - %s' % (self.name, self.targets,)


class Meta(object):
    def __init__(self, parser, options):
        self.references = {}
        self.parser = parser
        self.options = options
        self.nodes = {}
        self.networks = {}

        if not (hasattr(parser, 'get_name') and \
                hasattr(parser, 'file_extensions') and \
                hasattr(parser, 'parse') ):
            raise Exception(u'O parser informado não é válido.')


    def addSource(self, dirname, files):
        for file in files:
            if not file.split('.')[-1] in self.parser.file_extensions():
                continue

            f = open(os.path.join(dirname, file))
            try:
                r = Reference(self.parser.get_name(f.name), self.parser.parse(f.read()))
                self.references[r.name] = r
            finally:
                f.close()
                
        
    def add_node(self, name):
        if name in self.nodes:
            return
        self.nodes[name] = {'subsistema': name.split('.')[0]}

    def add_edge(self, network, src, dest):
        if not self.networks.has_key(network):
            self.networks[network] = []
        self.networks[network] += [(src, dest,)]        
                
    def calcNetwork(self):
        for ref in self.references.values():
            self.add_node(ref.name)
            for network, targets in ref.targets.items():
                for dest in targets:
                    self.add_node(dest)
                    self.add_edge(network, ref.name, dest)


def getDependencies(options):
    meta = Meta(DelphiParser(), options)

    os.path.walk(options.diretorio, Meta.addSource, meta)
    
    meta.calcNetwork()


    if options.xml:
        from renders.dynet import DynetRender
        m = DynetRender(meta)
        path = os.path.join(options.saida, options.name+'.xml')
        #try:
            #f = open(path, 'w+')
            #m.render(f)
        #finally:
            #f.close()

    if options.imagem:
        pass
        #from renders.img import ImgRender
        #m = ImgRender(meta)
        #path = os.path.join(options.saida, options.name+'.png')
        #try:
        #    f = open(path, 'w+')
        #    m.render(f)
        #finally:
        #    f.close()

    if options.javascript:
        from renders.protovis import ProtovisRender
        m = ProtovisRender(meta)
        path = os.path.join(options.saida, options.name+'.js')
        try:
            f = open(path, 'w+')
            m.render(f)
        finally:
            f.close()
    #for r in meta.references:
    #    print r.name, r.references

if __name__ == '__main__':
    from optparse import OptionParser, OptParseError
    import os
    usage = u'%prog [options] DIRETORIO_ORIGEM'
    parser = OptionParser(usage, version=version)
    parser.add_option('-s', '--saida', dest='saida', help=u'diretório de saída', default=".")
    parser.add_option('-n', '--name_prefix', dest='name', help=u'prefixo do nome de saída', default="dependencies")
    parser.add_option('-x', '--xml', dest='xml',
                      action="store_true", help=u'gerar arquivo XML DynetML')
    parser.add_option('-j', '--javascript', dest='javascript',
                      action="store_true", help=u'gerar arquivo Javascript')
    parser.add_option('-i', '--imagem', dest='imagem',
                      action="store_true", help=u'gerar arquivo de imagem', default=True)

    (options, args) = parser.parse_args()
    if (len(args)!=1):
        parser.print_help()
        exit(0)

    options.diretorio = args[0]
    if not os.path.exists(options.diretorio):
        raise OptParseError(u'diretório de origem não existe.')

    if not os.path.exists(options.saida):
        raise OptParseError(u'diretório de saída não existe.')

    getDependencies(options)

